#include "ds1302.h"

//定义时间数组，外部可调用
unsigned char DS1302_Time[9]={23, 3, 23 ,23, 59, 55, 4};//下标索引：年0 月1 日2 时3 分4 秒5 星期6                                       

//上电默认1，先初始化为0
void DS1302_Init(void)
{   
	DS1302_CE    = 0; _nop_();
	DS1302_SCLK  = 0; _nop_();
}


//单字节写(Command命令字(地址)，Data数据)，从低位开始写
void DS1302_WriteByte(unsigned char Command, unsigned char Data)
{
	unsigned char i;
	DS1302_CE = 1; _nop_();	
	for (i = 0; i < 8; i ++)	//写命令字
	{
		DS1302_IO = Command & (0x01<<i);//将命令字放在I/O线上，等待写入
		DS1302_SCLK = 1; 	//上升沿写入
		DS1302_SCLK = 0; 	// （准备下一次写入）
	}
	
	Data = ( ( (Data / 10) << 4) | (Data % 10) );	//BCD码的处理
	
	for (i = 0; i < 8; i ++)	//写数据
	{
		DS1302_IO = Data & (0x01<<i);//将数据放在I/O线上，等待写入
		DS1302_SCLK = 1;	//上升沿写入
		DS1302_SCLK = 0;
	}	
	DS1302_CE = 0; _nop_();
}

//单字节读，用上面的宏定义即可
unsigned char DS1302_ReadByte(unsigned char Command)
{
	unsigned char Data = 0x00;
	unsigned char i;
	Command |= 0x01;//变成读的地址
	
	DS1302_CE = 1; _nop_();	
	for (i = 0; i < 8; i ++)	//写命令字
	{
		DS1302_IO = Command & (0x01<<i);		
		DS1302_SCLK = 0;	//先给0后给1，因为时序图上少一个脉冲
		DS1302_SCLK = 1;
	}
	for (i = 0; i < 8; i ++)
	{
		DS1302_SCLK = 1;	//先给1后给0,模拟时序图
		DS1302_SCLK = 0;
		if(DS1302_IO == 1)	//读取端口是1
		{ Data |= (0x01<<i); }	//读数据操作
	}
	DS1302_CE = 0; _nop_();	
	DS1302_IO = 0; _nop_();	//修改的地方
	Data = (Data / 16 * 10) + (Data % 16);	//BCD码的处理
	return Data;	
}

//设置时间
void DS1302_SetTime(void)
{
	DS1302_WriteByte(DS1302_WP,     0x00);//解除芯片写保护
	DS1302_WriteByte(DS1302_YEAR,   DS1302_Time[0]);	//年
	DS1302_WriteByte(DS1302_MONTH,  DS1302_Time[1]);	//月
	DS1302_WriteByte(DS1302_DATE,   DS1302_Time[2]);	//日
	DS1302_WriteByte(DS1302_HOUR,   DS1302_Time[3]);	//时
	DS1302_WriteByte(DS1302_MINTUE, DS1302_Time[4]);	//分
	DS1302_WriteByte(DS1302_SECOND, DS1302_Time[5]);	//秒
	DS1302_WriteByte(DS1302_DAY,    DS1302_Time[6]);	//星期
	DS1302_WriteByte(DS1302_WP, 0x80);//此句WP给0x80，打开芯片写保护
}

//此函数读取时钟芯片的数据，写到数组DS1302_Time里
void DS1302_ReadTime(void)
{
	DS1302_Time[0] = DS1302_ReadByte(DS1302_YEAR);      //年//进去就被 或运算 置1，变成读,已经进行了BCD码的转换，，直接赋值即可
	DS1302_Time[1] = DS1302_ReadByte(DS1302_MONTH);     //月
	DS1302_Time[2] = DS1302_ReadByte(DS1302_DATE);	    //日
	DS1302_Time[3] = DS1302_ReadByte(DS1302_HOUR);	    //时
	DS1302_Time[4] = DS1302_ReadByte(DS1302_MINTUE);	//分
	DS1302_Time[5] = DS1302_ReadByte(DS1302_SECOND);	//秒
	DS1302_Time[6] = DS1302_ReadByte(DS1302_DAY);       //星期
}




/*底层驱动代码*/
/*
uchar Time[]={10,59,06,0,0,0,0};//秒 分 时 日 月 星期 年   

void Write_Ds1302( unsigned  char temp ) 
{
	unsigned char i;
	for (i = 0; i < 8; i ++)     	
	{ 
		SCK = 0;
		SDA = temp & 0x01;
		temp >>= 1; 
		SCK = 1;
	}
}   

void Write_Ds1302_Byte( unsigned char address,unsigned char dat )     
{
	uchar low, high;
 	RST = 0;	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
 	SCK = 0;	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
 	RST = 1; 	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); 
 	Write_Ds1302(address);	
	low  = dat % 10;	//BCD码的处理
	high = dat / 10;
	dat  = (high << 4) | low;
 	Write_Ds1302(dat);		
 	RST = 0; 
}

unsigned char Read_Ds1302_Byte ( unsigned char address )
{
 	unsigned char i, temp = 0x00;
	uchar low, high;
 	RST = 0;	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
 	SCK = 0;	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
 	RST = 1;	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
 	Write_Ds1302(address);
 	for (i = 0; i < 8; i ++) 	
 	{		
		SCK = 0;
		temp >>= 1;	
 		if (SDA)
 		temp |= 0x80;	
 		SCK = 1;
	} 
 	RST = 0;	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
 	SCK = 0;	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
	SCK = 1;	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
	SDA = 0;	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
	SDA = 1;	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
	high = temp >> 4;
	low  = temp & 0x0F;	//BCD码的处理
	temp = high * 10 + low;
	return (temp);			
}

//手写代码
void DS1302Init()
{
	uchar i, addr = 0x80;
	Write_Ds1302_Byte(0x8e, 0x00);
	for( i = 0; i < 7; i ++)
	{
		Write_Ds1302_Byte(addr,Time[i]);
		addr = addr + 2;
	}
	Write_Ds1302_Byte(0x8e, 0x80);
}

void Get_Time()
{
	uchar i,addr=0x81;
	Write_Ds1302_Byte(0x8e,0x00);
	for(i=0;i<7;i++)
	{
		Time[i]=Read_Ds1302_Byte(addr);
		addr=addr+2;
	}
	Write_Ds1302_Byte(0x8e,0x80); 
}
*/

